package com.cs.deviceManager.mqtt.ota;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * OTA 状态本地上报器（使用 Guava Cache）
 */
public class OtaLocalReporter implements FirmwareUpdater.UpdateCallback {

    private final OtaLocalCache cache;
    private final String deviceId;

    private final List<String> logList = new CopyOnWriteArrayList<>(); // ✅ 实例级日志
    private final Object logLock = new Object();

    private long firmwareSize = 0;
    private boolean isInitialized = false;

    public OtaLocalReporter(OtaLocalCache cache, String deviceId) {
        this.cache = cache;
        this.deviceId = deviceId;
    }

    private String now() {
        return java.time.LocalDateTime.now().format(
                java.time.format.DateTimeFormatter.ofPattern("HH:mm:ss")
        );
    }

    private void addLog(String msg) {
        String log = "[" + now() + "] " + msg;
        logList.add(0, log); // 最新在前
        // 仍然同步写入全局状态缓存（可选）
        // cache.addLog(deviceId, log); // ❌ 不再写全局 logMap
    }

    public List<String> getLogs() {
        return Collections.unmodifiableList(logList);
    }

    public void clearLogs() {
        logList.clear();
    }

    // --- 回调方法 ---
    @Override
    public void onStart() {
        System.out.println("✅ 开始更新");
        addLog("OTA 升级开始");

        long startTimeMillis = System.currentTimeMillis();
        OtaLocalCache.OtaStatus status = new OtaLocalCache.OtaStatus(
                "sending", 0, 0, 0, 0, 0, 0, startTimeMillis, ""
        );
        cache.putStatus(deviceId, status);
        isInitialized = true;
        firmwareSize = 0;
    }

    @Override
    public void onProgress(int progress, int sentBytes, int totalBytes, int elapsedTime) {
        if (!isInitialized) return;

        if (firmwareSize == 0) {
            firmwareSize = totalBytes;
            int totalPackets = (int) Math.ceil((double) totalBytes / 200);
            updateStatus("sending", progress, sentBytes, totalPackets, totalBytes, elapsedTime, "0");
        } else {
            updateStatus("sending", progress, sentBytes, -1, -1, elapsedTime, "0");
        }

        if (progress % 10 == 0 || progress == 99) {
            addLog("进度: " + progress + "% (" + sentBytes + "/" + totalBytes + ")");
        }
    }

    @Override
    public void onComplete(int totalTime) {
        System.out.println("🎉 更新完成");
        updateStatus("success", 100, firmwareSize, -1, -1, totalTime, "0");
        addLog("OTA 升级成功完成");
    }

    @Override
    public void onError(String error) {
        System.err.println("❌ 错误: " + error);
        updateStatus("failed", -1, -1, -1, -1, -1, error.length() > 500 ? error.substring(0, 500) : error);
        addLog("OTA 升级失败: " + error);
    }

    @Override
    public void onLog(String msg) {
        System.out.println(msg);
        addLog(msg);
    }


    // 辅助方法：更新状态（只更新传入的字段）
    private void updateStatus(String status, int progress, long sentBytes,
                              int totalPackets, long firmwareSize, int elapsedTime,
                              String error) {

        OtaLocalCache.OtaStatus old = cache.getStatus(deviceId);
        if (old == null) return;

        // 这里为了简单，直接用旧值 + 新值 构建新对象
        // 实际可用 Builder 模式优化
        OtaLocalCache.OtaStatus updated = new OtaLocalCache.OtaStatus(
                status != null ? status : old.status(),
                progress >= 0 ? progress : old.progress(),
                sentBytes >= 0 ? (int) (sentBytes / 200) : old.currentPacket(),
                totalPackets > 0 ? totalPackets : old.totalPackets(),
                sentBytes >= 0 ? sentBytes : old.sentBytes(),
                firmwareSize > 0 ? firmwareSize : old.firmwareSize(),
                elapsedTime >= 0 ? elapsedTime : old.elapsedTime(),
                old.startTime(),
                error != null ? error : old.errorMessage()
        );

        cache.putStatus(deviceId, updated);
    }
}